
package com.myproject.myblogserver.service.impl;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.myproject.myblogserver.contant.CommonConstants;
import com.myproject.myblogserver.converter.BlogDtoConverter;
import com.myproject.myblogserver.dto.PageResultDto;
import com.myproject.myblogserver.dto.blog.BlogPreviewDto;
import com.myproject.myblogserver.entity.Blog;
import com.myproject.myblogserver.entity.BlogTag;
import com.myproject.myblogserver.entity.User;
import com.myproject.myblogserver.service.IBlogService;
import com.myproject.myblogserver.service.IBlogTagService;
import com.myproject.myblogserver.service.IMyBlogPreviewService;
import com.myproject.myblogserver.service.IUserService;

@Service
public class MyBlogPreviewServiceImpl implements IMyBlogPreviewService {

        @Autowired
        private IBlogService blogService;

        @Autowired
        private IUserService userService;

        @Autowired
        private IBlogTagService blogTagService;

        @Override
        public PageResultDto<BlogPreviewDto> getPageResultBlogPreview(Integer pageIndex) {
                return getPageResultBlogPreviewByIds(null, pageIndex);
        }

        @Override
        public PageResultDto<BlogPreviewDto> getPageResultBlogPreviewByIds(List<Long> blogIds, Integer pageIndex) {
                var blogPreviewPage = blogService.lambdaQuery()
                                .eq(Blog::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
                                .in(blogIds != null, Blog::getId, blogIds)
                                .select(Blog::getId, Blog::getTitle, Blog::getSummary, Blog::getContent,
                                                Blog::getAuthorId, Blog::getCreatedAt)
                                .page(new Page<>(pageIndex, CommonConstants.DEFAULT_PAGE_SIZE));

                if (blogPreviewPage.getRecords().isEmpty()) {
                        return new PageResultDto<BlogPreviewDto>();
                }

                List<Long> currentPageBlogIds = blogPreviewPage.getRecords()
                                .stream()
                                .map(Blog::getId)
                                .collect(Collectors.toList());

                Map<Long, List<String>> tagsMap = blogTagService.lambdaQuery()
                                .in(BlogTag::getBlogId, currentPageBlogIds)
                                .eq(BlogTag::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
                                .select(BlogTag::getBlogId, BlogTag::getTagName)
                                .list()
                                .stream()
                                .collect(Collectors.groupingBy(
                                                BlogTag::getBlogId,
                                                Collectors.mapping(BlogTag::getTagName, Collectors.toList())));

                List<Long> authorIds = blogPreviewPage.getRecords()
                                .stream()
                                .map(Blog::getAuthorId)
                                .collect(Collectors.toList());

                Map<Long, User> userMap = userService.lambdaQuery()
                                .in(User::getId, authorIds)
                                .eq(User::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
                                .select(User::getId, User::getName, User::getAvatar)
                                .list()
                                .stream()
                                .collect(Collectors.toMap(User::getId, Function.identity()));

                List<BlogPreviewDto> blogPreviewList = blogPreviewPage.getRecords()
                                .stream()
                                .map(blog -> BlogDtoConverter.convertToBlogPreviewDto(
                                                blog,
                                                tagsMap.getOrDefault(blog.getId(), Collections.emptyList()),
                                                userMap.get(blog.getAuthorId())))
                                .collect(Collectors.toList());

                var pageResult = new PageResultDto<BlogPreviewDto>();
                pageResult.setContent(blogPreviewList);
                pageResult.setTotalPages(blogPreviewPage.getPages());
                return pageResult;
        }
}
